package edu.spbu.eclipse.addressbook.andrpodk;

import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

public class AddressBookEditor extends EditorPart{
	private Shell shell;	
	private ArrayList<Entry> addressBook;
	private boolean addressBookIsChanged=false;
	private boolean isSaveAsAllowed=false;
	private String currentFilePath;
	private String lastFinding="";
	private SaverLoader saverLoader;
	private Viewer viewer;
	private Editor editor;
	private boolean findResultsExist=false;

	public void doSave(IProgressMonitor monitor) {
		try{
			saverLoader.save(addressBook,currentFilePath);
			addressBookIsChanged=false;
			firePropertyChange(PROP_DIRTY);			
		}catch(IOException e1){
			MessageBox notExist=new MessageBox(shell,SWT.OK|SWT.ICON_WARNING);
			notExist.setText("Save Address Book");
			notExist.setMessage(currentFilePath+
			"\nThe file path doesn't exist.");
			notExist.open();
		}					
	}

	public void doSaveAs() {				
		Shell shell=getSite().getShell();
		FileDialog saveDialog=new FileDialog(shell,SWT.SAVE);		
		saveDialog.setFilterPath("C:/");
		saveDialog.setFilterExtensions(new String[]{"*.ab"});
		boolean anotherOpen=true;
		while(anotherOpen){
			String selectedFile=saveDialog.open();
			if(selectedFile!=null){
				if(new File(selectedFile).exists()){
					MessageBox overwrite= new MessageBox(shell,SWT.ICON_QUESTION|
							SWT.YES|SWT.NO|SWT.CANCEL);
					overwrite.setText("Save Address Book as...");
					overwrite.setMessage(selectedFile+" has already exists."+
					"\nDo you want to overwrite it?");
					switch(overwrite.open()){
					case SWT.YES:
						try{					
							saverLoader.save(addressBook,selectedFile);
							currentFilePath=selectedFile;
							addressBookIsChanged=false;
							firePropertyChange(PROP_DIRTY);							
							setPartName(saveDialog.getFileName());	
						}catch(IOException e1){
							MessageBox notExist=new MessageBox(shell,SWT.OK|SWT.ICON_WARNING);
							notExist.setText("Save Address Book as...");
							notExist.setMessage(selectedFile+
							"\nThe file path doesn't exist.");
							notExist.open();					
						}
						anotherOpen=false;
						break;
					case SWT.CANCEL:
						anotherOpen=false;
						break;													
					}
				}else{
					try{					
						saverLoader.save(addressBook,selectedFile);
						currentFilePath=selectedFile;
						addressBookIsChanged=false;
						firePropertyChange(PROP_DIRTY);						
						setPartName(saveDialog.getFileName());	
					}catch(IOException e1){
						MessageBox notExist=new MessageBox(shell,SWT.OK|SWT.ICON_WARNING);
						notExist.setText("Save Address Book as...");
						notExist.setMessage(selectedFile+
						"\nThe file path doesn't exist.");
						notExist.open();					
					}
					anotherOpen=false;
				}
			}else{
				anotherOpen=false;
			}
		}
	}


	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		if(input  instanceof IPathEditorInput){
			setSite(site);
			setInput(input);			
		}else throw new PartInitException("Invalid Input");					
	}

	public boolean isDirty() {
		return addressBookIsChanged;
	}

	public boolean isSaveAsAllowed() {
		return isSaveAsAllowed;
	}

	public void createPartControl(Composite parent){
		shell=parent.getShell();
		viewer=new Viewer(parent);
		saverLoader=new SaverLoader();
		editor=new Editor();
		currentFilePath=((IPathEditorInput)getEditorInput()).getPath().toString();	
		try{
			addressBook=saverLoader.load(currentFilePath);						
			viewer.show(addressBook);
			isSaveAsAllowed=true;
			setPartName(getEditorInput().getName());					
		}catch(IOException e1){
			MessageBox notFound=new MessageBox(shell,SWT.OK|SWT.ICON_WARNING);
			notFound.setText("Open Address Book");
			notFound.setMessage(currentFilePath+
			"\nThe file hasn't been found.");
			notFound.open();
		}catch(InvalidFileException ife){						
			switch(ife.getType()){
			case InvalidFileException.EMPTY_FILE_TYPE:
				MessageBox emptyFileDialog=new MessageBox(shell,
						SWT.ICON_WARNING|SWT.OK);
				emptyFileDialog.setText("Open Address Book");
				emptyFileDialog.setMessage(currentFilePath+
				"\nThe file is empty.");
				emptyFileDialog.open();
				break;						
			case InvalidFileException.INVALID_FORMAT_TYPE:
				MessageBox invalidFormatDialog=new MessageBox(shell,
						SWT.ICON_WARNING|SWT.OK);
				invalidFormatDialog.setText("Open Address Book");
				invalidFormatDialog.setMessage(currentFilePath+
				"\nThe file format is invalid.");
				invalidFormatDialog.open();
				break;
			}												
		}												
	}

	public void setFocus() {
		viewer.setFocus();		
	}

	public void performNewEntryAction() {
		new NewEntryDialog(shell,this);		
	}
	public void handleNewEntryData(Entry newEntry){
		int i=editor.addNew(addressBook,newEntry);
		viewer.refreshAdded(addressBook,i);
		addressBookIsChanged=true;
		firePropertyChange(PROP_DIRTY);	
	}

	public void performChangeEntryAction() {
		int i=viewer.getSelected();
		Entry edittingEntry=addressBook.get(i);
		new ChangeEntryDialog(shell,this,edittingEntry);		
	}
	public void handleChangeEntryData(Entry oldEntry,Entry modifiedEntry){
		Dimension indeces=editor.change(addressBook,oldEntry,modifiedEntry);
		viewer.refreshChanged(addressBook,indeces.width,indeces.height);
		addressBookIsChanged=true;
		firePropertyChange(PROP_DIRTY);		
	}

	public void performDeleteEntryAction() {
		if(addressBook.size()==1){
			MessageBox forbiddenAction=new MessageBox(shell,SWT.OK|SWT.ICON_WARNING);
			forbiddenAction.setText("Delete Entry");
			forbiddenAction.setMessage("The last entry removal is forbidden.");
			forbiddenAction.open();				
		}else{
			int i=viewer.getSelected();
			editor.delete(addressBook,i);       
			viewer.refreshDeleted(i);
			addressBookIsChanged=true;
			firePropertyChange(PROP_DIRTY);
		}					
	}

	public void performFindAction() {
		new FindDialog(shell,this,lastFinding);		
	}
	public void handleFindData(String stringToFind){
		lastFinding=stringToFind;
		if(viewer.find(stringToFind)){
			findResultsExist=true;				
		}else{
			MessageBox nothing=new MessageBox(shell,SWT.ICON_INFORMATION|
					SWT.OK);
			nothing.setText("Find");
			nothing.setMessage(stringToFind+
			"\nNothing is found.");
			nothing.open();
			findResultsExist=false;
		}
	}

	public void performFindNextAction() {
		if(findResultsExist){
			viewer.findNext();
		}else{
			performFindAction();	
		}		
	}
}	
